package cn.damong.service.weixin.impl;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.damong.dao.WeixinUserInfoMapper;
import cn.damong.service.response.ServiceResponse;
import cn.damong.service.weixin.IWeixinService;
import cn.damong.utils.common.JsonUtil;
import cn.damong.utils.http.HttpsUtil;
import cn.damong.weixin.mp.WeixinAuthType;
import cn.damong.weixin.mp.WeixinMPConfig;
import cn.damong.weixin.mp.WeixinUserInfo;

@Service("weixinService")
public class WeixinServiceImpl implements IWeixinService {
	@Autowired
	private WeixinMPConfig weixinConfig;

	private Logger logger = LoggerFactory.getLogger(WeixinServiceImpl.class);

	@Autowired
	private WeixinUserInfoMapper weixinUserInfoMapper;

	private final String WEIXIN_AUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
	private final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
	private final String USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";

	@Override
	public String getAuthUrl(WeixinAuthType weixinAuthType) {
		return this.getAuthUrl(weixinAuthType, weixinAuthType.toString());
	}
	
	@Override
    public String getAuthUrl(WeixinAuthType weixinAuthType, String state) {
	    String appid = weixinConfig.getAppId();
        String redirectUri = weixinConfig.getRedirectUri();
        return String.format(WEIXIN_AUTH_URL, appid, redirectUri, weixinAuthType.toString(), state);
    }
	
	@Override
    public String fetchAccessToken(String code) {
        String appid = weixinConfig.getAppId();
        String appSecret = weixinConfig.getAppSecret();
        String url = String.format(ACCESS_TOKEN_URL, appid, appSecret, code);
        return HttpsUtil.get(url);
    }

	@Override
	public ServiceResponse getOpenId(String code) {
		String result = this.fetchAccessToken(code);

		if (StringUtils.isBlank(result)) {
			return ServiceResponse.fail("Request accesstoken failed, no response!");
		}

		Map<Object, Object> map;
		try{
		    map = JsonUtil.jsonToMap(result);
		}catch(Exception e) {
		    logger.error("Resolve accesstoken response failed: {}", result);
		    return ServiceResponse.fail("Resolve accesstoken response failed: " + result);
		}
		Object openid = map.get("openid");
		if (openid == null) {
			return ServiceResponse.fail((String) map.get("errmsg"));
		} else {
			return ServiceResponse.success(openid);
		}
	}

	@Override
	public ServiceResponse getWeixinUserInfo(String code) {
	    String result = this.fetchAccessToken(code);

        if (StringUtils.isBlank(result)) {
            return ServiceResponse.fail("Request accesstoken failed, no response!");
        }

        Map<Object, Object> map;
        try{
            map = JsonUtil.jsonToMap(result);
        }catch(Exception e) {
            logger.error("Resolve accesstoken response failed: {}", result);
            return ServiceResponse.fail("Resolve accesstoken response failed: " + result);
        }
        
		Object openid = map.get("openid");
		if (openid == null) {
			return ServiceResponse.fail((String) map.get("errmsg"));
		} else {
			String access_token = (String) map.get("access_token");
			String url = String.format(USERINFO_URL, access_token, openid);

			result = HttpsUtil.get(url);

			logger.debug("Request url:" + url + " -->" + result);

			if (StringUtils.isBlank(result)) {
				return ServiceResponse.fail("GetWeixinUserInfo failed, snsapi_userinfo no response");
			}

			/**
			 * { "openid":" OPENID",
             * "nickname": NICKNAME,
             * "sex":"1",
             * "province":"PROVINCE"
             * "city":"CITY",
             * "country":"COUNTRY",
             * "headimgurl":"http:thirdwx.qlogo.cn/...",
             * "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
             * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
             * }
			 */
			try{
	            map = JsonUtil.jsonToMap(result);
	        }catch(Exception e) {
	            logger.error("Resolve userinfo response failed: {}", result);
	            return ServiceResponse.fail("Resolve userinfo response failed: " + result);
	        }
			if (map.containsKey("openid")) {
				WeixinUserInfo weixinUserInfo = new WeixinUserInfo();
				weixinUserInfo.setOpenid((String) map.get("openid"));
				weixinUserInfo.setNickname((String) map.get("nickname"));
				weixinUserInfo.setCity((String) map.get("city"));
				weixinUserInfo.setCountry((String) map.get("country"));
				weixinUserInfo.setHeadimgurl((String) map.get("headimgurl"));
				// weixinUserInfo.setPrivilege((String)map.get("privilege"));
				if(map.containsKey("unionid") && map.get("unionid") != null) {
				    weixinUserInfo.setUnionid((String) map.get("unionid"));
				}
				return ServiceResponse.success(weixinUserInfo);
			} else {
				return ServiceResponse.fail((String) map.get("errmsg"));
			}

		}
	}
	
	

	@Override
	public Integer saveWeixinUser(WeixinUserInfo weixinUserInfo) {
	    //TODO 需要自行实现持久化
		return null;
	}

}
